﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.Threading;
using ExORMDesginer.UserControls.CCodeEditer;
using ExtendPropertyLib.WPF;
using ExtendPropertyLib;
using System.Collections.ObjectModel;
using ExORMDesginer.Models;
using System.Windows.Input;
using MaxZhang.EasyEntities.Persistence;
using MaxZhang.EasyEntities.Persistence.SqlMap;
using System.Reactive.Linq;
using ExORMDesginer.Services;
using ExORMDesginer.RadWindow.Helper;

namespace ExORMDesginer.UserControls
{
    public class DatabaseExplorerViewModel : TabViewModel<DatabaseExplorerInfo>
    {
        private IWindowManager WindowManager{get{return  new RadWindowManager();}}

        public override void OnDoCreate(ExtendObject item, params object[] args)
        {
            base.OnDoCreate(item, args);

            this.ParametersViewModel = CreateView<ParametersListBoxViewModel>(true);

            SQLEditerTabs = new ObservableCollection<SQLEditerItemInfo>();
            //注册AddTab命令
            AddTabCommand = this.RegisterCommand(NewQuery);
            //注册Copy命令
            CopyCommand = this.RegisterCommand(Copy);
            //注册分析SQL命令
            ParseSQLCommand = this.RegisterCommand(ParseSQLForParameters);
            //注册调试命令
            DebugCommand = this.RegisterCommand(Debug);


            //Rx event for the tab index value changed
            var rxValueChangedEvent = Observable.FromEventPattern<ExtendPropertyValueChangedArgs>(v => DatabaseExplorerViewModel.TabIndexProperty.ValueChanged += v,
                                                                                              v => DatabaseExplorerViewModel.TabIndexProperty.ValueChanged -= v);
                                                                                                         
            rxValueChangedEvent.Delay(TimeSpan.FromMilliseconds(100))
                               .Subscribe(eve=> this.Sync(() => { TabIndexProperty_ValueChanged(eve.Sender, eve.EventArgs); }));

            
                
            this.ParametersViewModel.ParameterTypeChanged += ParametersViewModel_ParameterTypeChanged;
        }

        //监听参数列表中某参数的类型变化
        void ParametersViewModel_ParameterTypeChanged(object sender, EventArgs e)
        {
            if (TabIndex >= 0)
            {
                var parameter = sender as ParameterInfo;
                var editer = SQLEditerTabs[TabIndex].View as IEditer;
                string sql = editer.GetText();
                editer.SetText(Model.GetStringWithSqlParameterType(sql, parameter));
            }
        }

        //切换SQL-MAP命令，Tab页
        void TabIndexProperty_ValueChanged(object sender, ExtendPropertyValueChangedArgs e)
        {
            if (TabIndex >= 0)
            {
                this.ParametersViewModel.Model.Rest();
                this.ParseSQLForParameters();

            }
            else
            {
                this.ParametersViewModel.Model.Parameters.Clear();
            }
            ResultData = null;
        }
        #region Commands
        /// <summary>
        /// 添加数据库编辑器tab页命令
        /// </summary>
        public ICommand AddTabCommand{get;private set;}

        /// <summary>
        /// Copy命令
        /// </summary>
        public ICommand CopyCommand { set; get; }


        /// <summary>
        /// 分析SQL命令
        /// </summary>
        public ICommand ParseSQLCommand { set; get; }

        /// <summary>
        /// 调试命令
        /// </summary>
        public ICommand DebugCommand { set; get; }

        #endregion

        public static ExtendProperty ParametersViewModelProperty = RegisterProperty<DatabaseExplorerViewModel>(v => v.ParametersViewModel);
        /// <summary>
        /// 当前参数列表视图
        /// </summary>
        public ParametersListBoxViewModel ParametersViewModel { set { SetValue(ParametersViewModelProperty, value); } get { return (ParametersListBoxViewModel)GetValue(ParametersViewModelProperty); } }

        public static ExtendProperty ResultDataProperty = RegisterProperty<DatabaseExplorerViewModel>(v => v.ResultData);
        /// <summary>
        /// 当前查询结果
        /// </summary>
        public DataSet ResultData { set { SetValue(ResultDataProperty, value); } get { return (DataSet)GetValue(ResultDataProperty); } }

        public static ExtendProperty SqlMapListProperty = RegisterProperty<DatabaseExplorerViewModel>(v => v.SqlMapList);
        /// <summary>
        /// 载入的SQL-MAP列表
        /// </summary>
        public ObservableCollection<SqlMapCommand> SqlMapList { set { SetValue(SqlMapListProperty, value); } get { return (ObservableCollection<SqlMapCommand>)GetValue(SqlMapListProperty); } }


        public static ExtendProperty TabIndexProperty = ExtendProperty.RegisterProperty("TabIndex", typeof (DatabaseExplorerViewModel), -1);
        /// <summary>
        /// 表示选择tab页的第几项
        /// </summary>
        public int TabIndex { set { SetValue(TabIndexProperty, value); } get { return (int)GetValue(TabIndexProperty); } }

        public static ExtendProperty SQLEditerTabsProperty = RegisterProperty<DatabaseExplorerViewModel>(v => v.SQLEditerTabs);
        /// <summary>
        /// 绑定显示SQL语句编辑器Tab页的数据
        /// </summary>
        public ObservableCollection<SQLEditerItemInfo> SQLEditerTabs { set { SetValue(SQLEditerTabsProperty, value); } get { return (ObservableCollection<SQLEditerItemInfo>)GetValue(SQLEditerTabsProperty); } }

    

        /// <summary>
        /// 添加SQL编辑视图
        /// </summary>
        /// <param name="content"></param>
        public void AddTab(string title,string content,object tag)
        {
            SQLEditerTabs.Add(new SQLEditerItemInfo() { Title = title, SQL = content ,Tag = tag});
        }
        /// <summary>
        /// 打开SQL-MAP文件，并载入列表
        /// </summary>
        /// <param name="filePath"></param>
        public void OpenForFile(string filePath)
        {
            this.SqlMapList =  new ObservableCollection<SqlMapCommand>(Model.GetMapListForFile(filePath));
        }

        /// <summary>
        /// 分析SQL
        /// </summary>
        private  void ParseSQLForParameters()
        {

            if (TabIndex >= 0)
            {
                this.ParametersViewModel.Model.Rest();
                var editer = SQLEditerTabs[TabIndex].View as IEditer;
                string sql = editer.GetText();
                var awaiter = Model.GetCommandParameters(sql).GetAwaiter();
                this.ParametersViewModel.Model.SetParameters(awaiter.GetResult());
            }
        }

        /// <summary>
        /// 新建查询
        /// </summary>
        public void NewQuery()
        {
            if(Model.CurrentSqlMapItem!=null)
                AddTab(Model.CurrentSqlMapItem.Name, Model.CurrentSqlMapItem.SQL, Model.CurrentSqlMapItem);
        }

        /// <summary>
        /// 调试
        /// </summary>
        public void Debug()
        {

            if (TabIndex >= 0)
            {
                var sqlParameters = this.ParametersViewModel.Model.Parameters;
                if (sqlParameters.Any(s => string.IsNullOrEmpty(s.Value)))
                {
                    WindowManager.ShowMessage("命令参数不能为空！");
                    return;
                }
                var command = SQLEditerTabs[TabIndex].Tag as SqlMapCommand;
                command.SQL = SQLEditerTabs[TabIndex].SQL;
                

                command.Parameters = Model.ConvertParametersToMapParameters(sqlParameters);
                using (DbSession.Default)
                {
                    command.DataProvider = DbSession.Default.Provider;
                    ResultData = command.Query();
                }


            }
            else
            {
               
                WindowManager.ShowMessage("没有可运行的服务！");

            }
        }



        /// <summary>
        /// 复制
        /// </summary>
        public void Copy()
        {
            if (TabIndex > -1)
            {
                var editer = SQLEditerTabs[TabIndex].View as IEditer;
                string sql = editer.GetText();
            
                WindowManager.ShowMessage(sql);
            }
        }

        public void Close()
        {
            TabIndex = -1;
            Model.ClearSqlMaps();
        }


    }
}
